package uk.ac.bbk.dcs.pakdd2014.train;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.HashMap;

import uk.ac.bbk.dcs.pakdd2014.*;

/* This app loads the training data and trains a classifier to specification */

public class Train {
	
	
	public static HashMap<Integer,HashMap<Integer,SalesDate>> parseST() throws IOException{
		
		HashMap<Integer,HashMap<Integer,SalesDate>> hm= new HashMap<Integer,HashMap<Integer,SalesDate>>();
		File f= new File("data_filtered/SaleTrain.csv");
		BufferedReader br = new BufferedReader(new FileReader(f));
		String s;
		while((s=br.readLine())!=null){
			String[] arr=s.split(",");
			
			int mod=Integer.parseInt(arr[0]);
			int com= Integer.parseInt(arr[1]);
			int quantity = Integer.parseInt(arr[3]);
			
			String[] date=arr[2].split("/");
			int month=Integer.parseInt(date[1]);
			int year=Integer.parseInt(date[2]);

			if(!hm.containsKey(mod))
			{
				hm.put(mod,new HashMap<Integer,SalesDate>());
			}
			HashMap<Integer,SalesDate> ym = hm.get(mod);
			if(ym.containsKey(com)){
				ym.get(com).addSale(year, month, quantity);
			} else{
				SalesDate sd=new SalesDate(mod,com);
				sd.addSale(year, month, quantity);
				ym.put(com, sd);
			}
		}
		br.close();
		return hm;
	}
	
	public static void main(String[] args) throws Exception {
		try
	    {
			HashMap<Integer,HashMap<Integer,SalesDate>> sales=parseST();
	        FileInputStream fileIn = new FileInputStream("datasets/MCLifeProbability.serialized");
	        ObjectInputStream in = new ObjectInputStream(fileIn);
	        HashSet<MCLifeProbability> mclps = (HashSet<MCLifeProbability>) in.readObject();
	        in.close();
	        fileIn.close();
	        HashMap<Integer,HashMap<Integer,MCLifeProbability>> accessor = new HashMap<Integer,HashMap<Integer,MCLifeProbability>>();
	        for(MCLifeProbability mclp : mclps)
	        {
	        	if(!accessor.containsKey(mclp.getModule()))
	        	{
	        		accessor.put(mclp.getModule(), new HashMap<Integer,MCLifeProbability>());
	        	}
	        	HashMap<Integer,MCLifeProbability> perModule = accessor.get(mclp.getModule());
	        	if(!perModule.containsKey(mclp.getComponent()))
	        	{
	        		perModule.put(mclp.getComponent(), mclp);
	        	}
	        	else
	        	{
	        		throw new Exception("duplicate distribution for M" + mclp.getModule() + ", P" + mclp.getComponent());
	        	}
	        }
			File f= new File("data/Output_TargetID_Mapping.csv");
			BufferedReader br = new BufferedReader(new FileReader(f));
			String s;
			int lineNumber = 1;
			ArrayList<PredictionLine> predictionLines = new ArrayList<PredictionLine>();
			while((s=br.readLine())!=null){
				String[] arr=s.split(",");
				if(arr[0].equals("module_category"))
				{
					continue;
				}
				int module = Integer.parseInt(arr[0].substring(1));
				int component = Integer.parseInt(arr[1].substring(1));
				int year = Integer.parseInt(arr[2]);
				int month = Integer.parseInt(arr[3]);
				predictionLines.add(new PredictionLine(module,component,lineNumber,year,month));
				lineNumber++;
			}
			br.close();
			DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
			java.util.Date date = new java.util.Date();
			try
			{
				PrintWriter output = new PrintWriter("data/output-" /*+ dateFormat.format(date)*/ + ".csv", "UTF-8");
				output.println("id,target");
				for(PredictionLine p : predictionLines)
				{
					SalesDate sale = sales.get(p.module).get(p.component);
					int cumulativeRepairs = 0;
					MCLifeProbability prob = accessor.get(p.module).get(p.component);
					HashMap<Date,Integer> sold = sale.getSold();
					for(Date d : sold.keySet())
					{
						int qty = sold.get(d);
						int age = (p.year - d.getYear()) * 12 + p.month - d.getMonth();
						if (age > 0)
						{
							try
							{
								cumulativeRepairs += prob.getPrediction(age) * qty;
							}
							catch(org.apache.commons.math3.exception.NotStrictlyPositiveException e)
							{
								System.out.println("zero variance in module " + p.module + ", component " + p.component);
							}
						}
					}
					output.println(p.line + "," + cumulativeRepairs);
				}
				output.close();
			} catch (Exception e) {
				e.printStackTrace();
			} 
			System.out.println("done");
	    }
		catch(IOException i)
	    {
	        i.printStackTrace();
	        return;
	    }
		catch(ClassNotFoundException c)
	    {
	        System.out.println("Employee class not found");
	        c.printStackTrace();
	        return;
	    }
	}

}
